use16
;bits 16
org 0x7c00

%define ENTRY_ADDRESS 0x7f00
%define STACK_SIZE 50
%define CODE_SEG     0x0008
%define DATA_SEG     0x0010


global start
start:



    ;open A20
    mov ax, 0x2401
    int 0x15

    ;打开A20地址线
;enable_a20:
    ;in     al,0x64
    ;test   al,2
    ;jnz    enable_a20
    ;mov    al,0xdf
    ;out    0x64,al



    ;first set stack to use functions
    xor ax,ax
    mov ss,ax

    mov ds,ax
    mov es,ax
    mov fs,ax
    mov gs,ax
    mov sp,0x7c00





    mov ax,bootMsg  ;input parameter msg
	mov cx,bootMsgLen		;str length
	mov dh,00h ;第1行
	call ShowMsg	;output str

	;load second Second Sector Code data
	;Have to load it! Or errors will occur.
	call LoadSecondSectorRun

    call read_next_15_sectors











    mov ax,secondSectorRunMsg  ;input parameter msg
	mov cx,ssrmLen		;str length
    mov dh,02h ;第3行
   	call ShowMsg	;output str

    cli

    lgdt [gdt_pointer]
    mov ebx,cr4
    or ebx, 0100000b                ; Set the PAE and PGE bit.
    mov cr4, ebx
   ;open pe 保护模式 开
    mov ebx,cr0
    or ebx,0x00000001
    mov cr0,ebx
    ;jmp end_of_sector
    jmp into_64_env




read_next_15_sectors:
    mov bx, ENTRY_ADDRESS
    mov ah, 0x02 ; read sector function
    mov al, 15   ; read dh sectors
    mov ch, 0x00 ; read from cyl 0
    mov dh, 0x00 ; read from head 0
    mov cl, 0x03 ; start from sec 3
        ; since the bootloader is at sec 1
    int 0x13 ; drive interrupt

    ret

;stack_base_address_end:
 ;   times STACK_SIZE db 0
;stack_base_address_begin:
 ;   times 20 db 0

ShowMsg:
	mov bp,ax
	mov ax,01301h
	mov bx,000ch
	mov dl,0 ;列 dh 是行
	int 10h
	ret

	;载入第二个扇区数据,从磁盘到内存
LoadSecondSectorRun:
	mov ah,02h                            ;读磁盘扇区
    mov al,01h                            ;读取1个扇区
    mov ch,00h                            ;起始磁道
    mov cl,02h                            ;起始扇区
    mov dh,00h                            ;磁头号
    mov dl,00h                            ;驱动器号
    mov bx,SecondSectorRun                             ;存储缓冲区
    int 13h
    ret

bootMsg:
	db "Hello,World!"
	bootMsgLen equ $-bootMsg
	;$ -current position

end_of_sector:
    ;bits 64
    ;call 0x7e00
    call 0x7e00

    jmp into_64_env

use64
into_64_env:
    sti
    call ENTRY_ADDRESS
    jmp $


gdt:
gdt_blank:
    dq 0x0000000000000000             ; Null Descriptor - should be present.
gdt_code:
    dq 0x00209A0000000000            ; 64-bit code descriptor (exec/read).
gdt_data:
    dq 0x0000920000000000             ; 64-bit data descriptor (read/write).
gdt_pointer:
    dw $ - gdt - 1 ; size
    dd gdt         ; base

times 510-($-$$) db 0
dw 0xaa55

use16
SecondSectorRun:
	;output secondSectorRunMsg -- first msg
	mov ax,secondSectorRunMsg  ;input parameter msg
	mov cx,ssrmLen		;str length
	mov dh,01h ;第2行
	call ShowMsg	;output str
	ret



secondSectorRunMsg:
	db "Loaded Second Sector Data Successfully!"
	ssrmLen equ $-secondSectorRunMsg
times 512*2-($-$$) db 0


